#include "ChannelManagerThreadSafe.h"
#include "Channel.h"
#include "Mutex.h"

IChannelManager*	ChannelManagerThreadSafe::_instance = NULL;

ChannelManagerThreadSafe::ChannelManagerThreadSafe()
{
	this->LoadChannel();
	this->_mtx = new Mutex();
}

IChannelManager*	ChannelManagerThreadSafe::GetChannelManager(void)
{
	if (!ChannelManagerThreadSafe::_instance)
		ChannelManagerThreadSafe::_instance = new ChannelManagerThreadSafe();
	return ChannelManagerThreadSafe::_instance;
}

const unsigned int	ChannelManagerThreadSafe::LoadChannel()
{
	//load from database
	return 0;
}

const unsigned int	ChannelManagerThreadSafe::CreateChannel(const std::string& name, const unsigned int maxNameLenght, const std::string& password, const unsigned int maxPasswordLenght, const std::string& motd, const unsigned int maxMotdLenght, const std::string& description, const unsigned int maxDescriptionLenght, const bool visible, const unsigned int maxUser, const unsigned int maxTalker)
{
	IChannel*	channel = new Channel(1, name, maxNameLenght, password, maxPasswordLenght, motd, maxMotdLenght, description, maxDescriptionLenght, visible, maxUser, maxTalker);
	this->_mtx->Lock();
	this->_channel.push_back(channel);
	this->_mainChannel.push_back(channel);
	this->_mtx->Unlock();
	return 0;
}

const unsigned int	ChannelManagerThreadSafe::CreateChannel(IChannel* parent, const std::string& name, const unsigned int maxNameLenght, const std::string& password, const unsigned int maxPasswordLenght, const std::string& motd, const unsigned int maxMotdLenght, const std::string& description, const unsigned int maxDescriptionLenght, const bool visible, const unsigned int maxUser, const unsigned int maxTalker)
{
	IChannel*	channel = new Channel(1, parent, name, maxNameLenght, password, maxPasswordLenght, motd, maxMotdLenght, description, maxDescriptionLenght, visible, maxUser, maxTalker);
	this->_mtx->Lock();
	this->_channel.push_back(channel);
	this->_mtx->Unlock();
	return 0;
}

const unsigned int	ChannelManagerThreadSafe::DeleteChannel(IChannel* channel)
{
	this->_mtx->Lock();
	if (!channel->HaveParent())
		this->_mainChannel.remove(channel);
	channel->DeleteChannel();
	this->_channel.remove(channel);
	this->_mtx->Unlock();
	return 0;
}

const unsigned int	ChannelManagerThreadSafe::DeleteChannel(const unsigned int id)
{
	this->_mtx->Lock();
	IChannel*	channel = this->GetChannel(id);
	this->DeleteChannel(channel);
	this->_mtx->Unlock();
	return 0;
}

const unsigned int	ChannelManagerThreadSafe::DeleteChannel(const std::string& pattern)
{
	this->_mtx->Lock();
	IChannel* channel = this->GetChannel(pattern);
	this->DeleteChannel(channel);
	this->_mtx->Unlock();
	return 0;
}

const unsigned int	ChannelManagerThreadSafe::MoveChannel(IChannel* channel, IChannel* parent)
{
	this->_mtx->Lock();
	channel->SetParent(parent);
	this->_mtx->Unlock();
	return 0;
}

const unsigned int	ChannelManagerThreadSafe::MoveChannel(IChannel* channel, const unsigned int idParent)
{
	this->_mtx->Lock();
	channel->SetParent(this->GetChannel(idParent));
	this->_mtx->Unlock();
	return 0;
}

const unsigned int	ChannelManagerThreadSafe::MoveChannel(IChannel* channel, const std::string& patternParent)
{
	this->_mtx->Lock();
	channel->SetParent(this->GetChannel(patternParent));
	this->_mtx->Unlock();
	return 0;
}

const unsigned int	ChannelManagerThreadSafe::MoveChannel(const unsigned int idChannel, IChannel* parent)
{
	this->_mtx->Lock();
	this->GetChannel(idChannel)->SetParent(parent);
	this->_mtx->Unlock();
	return 0;
}

const unsigned int	ChannelManagerThreadSafe::MoveChannel(const unsigned int idChannel, const unsigned int idParent)
{
	this->_mtx->Lock();
	this->GetChannel(idChannel)->SetParent(this->GetChannel(idParent));
	this->_mtx->Unlock();
	return 0;
}

const unsigned int	ChannelManagerThreadSafe::MoveChannel(const unsigned int idChannel, const std::string& patternParent)
{
	this->_mtx->Lock();
	this->GetChannel(idChannel)->SetParent(this->GetChannel(patternParent));
	this->_mtx->Unlock();
	return 0;
}

const unsigned int	ChannelManagerThreadSafe::MoveChannel(const std::string& patternChannel, IChannel* parent)
{
	this->_mtx->Lock();
	this->GetChannel(patternChannel)->SetParent(parent);
	this->_mtx->Unlock();
	return 0;
}

const unsigned int	ChannelManagerThreadSafe::MoveChannel(const std::string& patternChannel, const unsigned int idParent)
{
	this->_mtx->Lock();
	this->GetChannel(patternChannel)->SetParent(this->GetChannel(idParent));
	this->_mtx->Unlock();
	return 0;
}

const unsigned int	ChannelManagerThreadSafe::MoveChannel(const std::string& patternChannel, const std::string& patternParent)
{
	this->_mtx->Lock();
	this->GetChannel(patternChannel)->SetParent(this->GetChannel(patternParent));
	this->_mtx->Unlock();
	return 0;
}

//bof bof comme methodes get, si plusieur resultat ou pas trouve --> pouf dans le mur
IChannel*	ChannelManagerThreadSafe::GetChannel(const unsigned int id)
{
	this->_mtx->Lock();
	std::list<IChannel*>::iterator	iteCurrent = this->_channel.begin();
	std::list<IChannel*>::iterator	iteEnd = this->_channel.end();
	while (iteCurrent != iteEnd)
	{
		if ((*iteCurrent)->GetId() == id)
		{
			this->_mtx->Unlock();
			return *iteCurrent;
		}
		++iteCurrent;
	}
	this->_mtx->Unlock();
	return NULL;
}

IChannel*	ChannelManagerThreadSafe::GetChannel(const std::string& pattern)
{
	this->_mtx->Lock();
	std::list<IChannel*>::iterator	iteCurrent = this->_channel.begin();
	std::list<IChannel*>::iterator	iteEnd = this->_channel.end();
	while (iteCurrent != iteEnd)
	{
		if ((*iteCurrent)->GetName() == pattern)
		{
			this->_mtx->Unlock();
			return *iteCurrent;
		}
		++iteCurrent;
	}
	this->_mtx->Unlock();
	return NULL;
}

/*
const std::list<IChannel*>&	ChannelManagerThreadSafe::GetChannelList(const std::string&) const
{

	return 0;
}
*/